import vlc
import tkinter as tk
from tkinter import ttk,filedialog,messagebox
import threading
import time
import os,sys
#from PIL import Image, ImageTk
 
# 初始化主窗口（带蛇年主题）
root = tk.Tk()
root.title("兽控放映室 🐾")
root.geometry("800x600") 
 
# 创建VLC实例（启用硬件加速）
instance = vlc.Instance("--no-xlib --avcodec-hw=any")
player = instance.media_player_new() 

# 状态变量
is_playing = False
is_updating = False
last_error = None

# 错误检测和显示
def show_error_window(error_message):
    """显示自定义错误窗口"""
    error_window = tk.Toplevel(root)
    error_window.title("呜咪~爪爪按错地方了！(>﹏<)")
    error_window.geometry("600x400")
    error_window.resizable(False, False)
    
    # 设置窗口居中
    error_window.transient(root)
    error_window.grab_set()
    
    # 创建主框架
    main_frame = tk.Frame(error_window)
    main_frame.pack(fill=tk.BOTH, expand=True)
    
    try:
        # 加载背景图片
        if os.path.exists("assets\\err.png"):
            bg_image = tk.PhotoImage(file="assets\\err.png")
            #bg_image = bg_image.resize((600, 400), Image.Resampling.LANCZOS)
            #bg_photo = ImageTk.PhotoImage(bg_image)
            
            # 背景标签
            bg_label = tk.Label(main_frame, image=bg_image)
            bg_label.image = bg_image  # 保持引用
            bg_label.pack(fill=tk.BOTH, expand=True)
            
            # 错误信息框架（右侧一半）
            
            
        else:
            # 如果没有背景图片，使用默认样式
            pass
    except Exception as e:
        # 如果图片加载失败，使用默认样式
        pass
    
    
    
    # 错误信息
    error_text = tk.Text(main_frame, wrap=tk.WORD, width=35, height=15,
                        font=("Arial", 10,'bold'), bg='white' if os.path.exists("assets\\err.png") else '#ffebee',
                        fg='#333333', relief=tk.FLAT, bd=0)
    error_text.place(y=10, x=400)
    
    # 插入错误信息
    error_text.insert(tk.END, error_message)
    '''
    error_text.insert(tk.END, "可能的解决方案：\n")
    error_text.insert(tk.END, "• 检查文件路径是否正确\n")
    error_text.insert(tk.END, "• 确认文件格式是否支持\n")
    error_text.insert(tk.END, "• 检查文件是否损坏\n")
    error_text.insert(tk.END, "• 尝试重新选择文件\n")
    
    error_text.config(state=tk.DISABLED)
    
    # 按钮框架
    button_frame = tk.Frame(main_frame, bg='white' if os.path.exists("assets\\err.png") else '#ffebee')
    button_frame.pack(pady=10)
    
    # 确定按钮
    ok_button = tk.Button(button_frame, text="确定", 
                         command=error_window.destroy,
                         font=("Arial", 10), bg='#d32f2f', fg='white',
                         relief=tk.FLAT, padx=20, pady=5)
    ok_button.pack(side=tk.LEFT, padx=5)
    
    # 重试按钮
    retry_button = tk.Button(button_frame, text="重新选择文件", 
                            command=lambda: [error_window.destroy(), select_new_file()],
                            font=("Arial", 10), bg='#1976d2', fg='white',
                            relief=tk.FLAT, padx=20, pady=5)
    retry_button.pack(side=tk.LEFT, padx=5)
'''
def select_new_file():
    """重新选择文件"""
    try:
        pth = filedialog.askopenfilename()
        if pth:
            pth = pth.replace("/", "\\")
            media = instance.media_new_path(pth)
            player.set_media(media)
            player.audio_set_volume(volume_var.get())
            stop_video()  # 重置状态
    except Exception as e:
        show_error_window(str(e))

def check_vlc_error():
    """检查VLC播放器错误状态"""
    global last_error
    
    try:
        # 检查播放器状态
        state = player.get_state()
        
        # VLC状态码
        # 0: NothingSpecial, 1: Opening, 2: Buffering, 3: Playing, 4: Paused, 5: Stopped, 6: Ended, 7: Error
        
        if state == 7:  # 错误状态
            # 获取错误信息
            error_msg = "兽兽在偷懒睡觉..."
            
            # 检查媒体状态
            media = player.get_media()
            if media:
                media_state = media.get_state()
                if media_state == 7:  # 媒体错误
                    error_msg = "这个爪印格式读不懂啦~"
                elif media_state == 6:  # 媒体结束
                    error_msg = "媒体文件已结束"
            
            # 检查文件是否存在
            if player.get_media():
                media_path = player.get_media().get_mrl()
                if media_path and not os.path.exists(media_path.replace("file:///", "").replace("file://", "")):
                    error_msg = f"找不到藏起来的毛球啦！\n{media_path}"
            
            # 避免重复显示相同错误
            if error_msg != last_error:
                last_error = error_msg
                show_error_window(error_msg)
                return True
                
    except Exception as e:
        error_msg = str(e)
        if error_msg != last_error:
            last_error = error_msg
            show_error_window(error_msg)
            return True
    
    return False

# 回调函数
def on_progress_change(value):
    """进度条拖拽时的回调"""
    if not is_updating and player.get_media():
        # 计算目标时间位置
        total_time = player.get_length()
        if total_time > 0:
            target_time = int(float(value) / 100 * total_time)
            player.set_time(target_time)

def on_volume_change(value):
    """音量滑块变化时的回调"""
    volume = int(float(value))
    player.audio_set_volume(volume)

def format_time(milliseconds):
    """格式化时间显示"""
    if milliseconds < 0:
        return "00:00"
    seconds = milliseconds // 1000
    minutes = seconds // 60
    seconds = seconds % 60
    return f"{minutes:02d}:{seconds:02d}"

def update_progress():
    """更新播放进度和时间显示"""
    global is_updating
    try:
        # 检查是否有错误
        if check_vlc_error():
            return
            
        if player.get_media() and is_playing:
            is_updating = True
            
            # 获取当前播放状态
            current_time = player.get_time()
            total_time = player.get_length()
            
            if total_time > 0:
                # 更新进度条
                progress = (current_time / total_time) * 100
                progress_var.set(progress)
                
                # 更新时间显示
                current_str = format_time(current_time)
                total_str = format_time(total_time)
                time_label.config(text=f"🕒 时间: {current_str} / {total_str}")
            
            is_updating = False
        
    except Exception as e:
        show_error_window(str(e))
    
    # 每100ms更新一次
    root.after(100, update_progress)

def play_video():
    """播放视频"""
    global is_playing
    try:
        if not player.get_media():
            show_error_window("快选媒体文件呀~")
            return
        
        player.play()
        is_playing = True
        
        # 延迟检查播放状态
        root.after(1000, check_play_status)
        
    except Exception as e:
        show_error_window(str(e))

def check_play_status():
    """检查播放状态，如果播放失败则显示错误"""
    if is_playing:
        state = player.get_state()
        if state == 7:  # 错误状态
            check_vlc_error()
        elif state == 3:  # 正在播放
            pass  # 正常播放
        elif state in [0, 1, 2]:  # 准备中
            # 继续检查
            root.after(500, check_play_status)

def pause_video():
    """暂停视频"""
    global is_playing
    try:
        player.pause()
        is_playing = not is_playing
    except Exception as e:
        show_error_window(str(e))

def stop_video():
    """停止视频"""
    global is_playing
    try:
        player.stop()
        is_playing = False
        progress_var.set(0)
        time_label.config(text="🕒 时间: 00:00 / 00:00")
    except Exception as e:
        show_error_window(str(e))

# 视频显示区域
video_frame = ttk.Frame(root)
video_frame.pack(fill=tk.BOTH,  expand=True)

# 控制面板
control_frame = ttk.Frame(root)
control_frame.pack(fill=tk.X, padx=5, pady=5)

# 播放进度条
progress_frame = ttk.Frame(control_frame)
progress_frame.pack(fill=tk.X, pady=2)

# 时间显示标签
time_label = ttk.Label(progress_frame, text="🕒 时间: 00:00 / 00:00")
time_label.pack(side=tk.LEFT)

# 进度条
progress_var = tk.DoubleVar()
style = ttk.Style()
style.configure( 
    'fur.Horizontal.TScale',
    background='#F5DEB3',  # 麦色底纹（象征丰收）
    troughcolor='#0000ff', # 棕色轨道（蛇年大地色）
    bordercolor='#000000', # 边框色（仿蛇皮）
    gripcount=7,           # 乙巳年幸运数 
    arrowsize=15           # 放大箭头（便于触控）
)
progress_bar = tk.Scale(progress_frame, from_=0, to=100, orient=tk.HORIZONTAL, 
                        variable=progress_var, command=on_progress_change)
progress_bar.configure( 
    
    background='#00DEB3',  # 麦色底纹（象征丰收）
    troughcolor='#001074', # 棕色轨道（蛇年大地色）
    activebackground='#000080', # 边框色（仿蛇皮）
    foreground="#000090",           # 乙巳年幸运数 
    highlightbackground="#000055"           # 放大箭头（便于触控）
)
progress_bar.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=5)

# 音量控制
volume_frame = ttk.Frame(control_frame)
volume_frame.pack(fill=tk.X, pady=2)

volume_label = ttk.Label(volume_frame, text="🔊 音量:")
volume_label.pack(side=tk.LEFT)

volume_var = tk.IntVar(value=100)  # 默认音量100%
volume_scale = tk.Scale(volume_frame, from_=0, to=100, orient=tk.HORIZONTAL,
                        variable=volume_var, command=on_volume_change)
volume_scale.configure( 
    
    background='#00DEB3',  # 麦色底纹（象征丰收）
    troughcolor='#001074', # 棕色轨道（蛇年大地色）
    activebackground='#000080', # 边框色（仿蛇皮）
    foreground="#000090",           # 乙巳年幸运数 
    highlightbackground="#000055"           # 放大箭头（便于触控）
)
volume_scale.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=5)

# 必须延迟获取窗口ID（Tkinter特性）
def setup_vlc():
    try:
        win_id = video_frame.winfo_id()
        print(win_id)
        player.set_hwnd(win_id)   # Windows系统
        # Linux系统用: player.set_xwindow(win_id) 
        '''
"furry_video"	"兽兽专属视频"	本地化分类
"furry_file"	"毛绒音频档案"	拟物化描述
"furry_files"	"所有爪爪文件"	统一主题词
'''
        pth = filedialog.askopenfilename(
            title="快选个毛茸茸的媒体文件啦~",
            filetypes=[
                ("兽兽专属视频", "*.mp4 *.avi *.mkv *.mov *.wmv *.flv *.webm *.m4v"),
                ("毛绒音频档案", "*.mp3 *.wav *.flac *.aac *.ogg *.wma"),
                ("所有爪爪文件", "*.*")
            ]
        ) if len(sys.argv)<2 else sys.argv[1]
        
        if not pth:
            show_error_window("没有毛茸茸可看...本兽先睡啦 \nzZZ")
            #root.quit()
            return
            
        pth = pth.replace("/", "\\")
        print(f"🐾 选中: {pth}")
        
        # 检查文件是否存在
        if not os.path.exists(pth):
            show_error_window(f"找不到藏起来的毛球啦！\n{pth}")
            return
        
        # 加载媒体文件
        media = instance.media_new_path(pth) 
        player.set_media(media)
        
        # 设置初始音量
        player.audio_set_volume(volume_var.get())
        
        # 开始更新进度
        update_progress()
        #raise Exception("fur")
    except Exception as e:
        show_error_window(str(e)) 
 
root.after(100,  setup_vlc)  # 延迟100ms确保窗口就绪
def choosefile():
    pth = filedialog.askopenfilename(
            title="挑选你的毛球录像带~",
            filetypes=[
                ("兽兽专属视频", "*.mp4 *.avi *.mkv *.mov *.wmv *.flv *.webm *.m4v"),
                ("毛绒音频档案", "*.mp3 *.wav *.flac *.aac *.ogg *.wma"),
                ("所有爪爪文件", "*.*")
            ]
        )
        
    if not pth:
        show_error_window("没有毛茸茸可看...本兽先睡啦\nzZZ")
        #root.quit()
        return
            
    pth = pth.replace("/", "\\")
    print(f"🐾 选中: {pth}")
        
        # 检查文件是否存在
    if not os.path.exists(pth):
        show_error_window(f"找不到藏起来的毛球啦！\n{pth}")
        return
        
        # 加载媒体文件
    media = instance.media_new_path(pth) 
    player.set_media(media)
    update_progress()
# 控制按钮区域
button_frame = ttk.Frame(root)
button_frame.pack(fill=tk.X, padx=5, pady=5)
playi=tk.PhotoImage(file="assets\\play.png")
pausei=tk.PhotoImage(file="assets\\pause.png")
stopi=tk.PhotoImage(file="assets\\stop.png")
fi=tk.PhotoImage(file="assets\\file.png")
# 简单控制按钮 
ttk.Button(button_frame, image=playi, command=play_video).pack(side=tk.LEFT, padx=2) 
ttk.Button(button_frame, image=pausei, command=pause_video).pack(side=tk.LEFT, padx=2)
ttk.Button(button_frame, image=stopi, command=stop_video).pack(side=tk.LEFT, padx=2)
ttk.Button(button_frame, image=fi, command=choosefile).pack(side=tk.LEFT, padx=2)
 
root.mainloop()  
